package egar

type Set interface {
	Add(values interface{}) bool
	Remove(value interface{})
	Len() int
	Exists(value interface{}) bool
	Clear()
	ForEach(callback func(interface{}) bool)
}

type threadUnsafeSet map[interface{}]struct{}

func (s threadUnsafeSet) Add(value interface{}) bool {
	prevLen := len(s)
	s[value] = struct{}{}
	return prevLen != len(s)
}

func (s threadUnsafeSet) Remove(value interface{}) {
	delete(s, value)
}

func (s threadUnsafeSet) Len() int {
	return len(s)
}

func (s threadUnsafeSet) Exists(value interface{}) bool {
	_, exists := s[value]
	return exists
}

func (s threadUnsafeSet) Clear() {
	for key := range s {
		delete(s, key)
	}
}

func (s threadUnsafeSet) ForEach(callback func(interface{}) bool) {
	for key := range s {
		if !callback(key) {
			break
		}
	}
}

func NewThreadUnsafeSet() Set {
	return make(threadUnsafeSet)
}
